package alarm

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"net/url"
	"strconv"
	"time"

	"gitee.com/daledi/public/options"
	"gitee.com/daledi/public/utils"
	"gitee.com/daledi/public/vmap"
	"github.com/parnurzeal/gorequest"
	"github.com/patrickmn/go-cache"
)

type RespMsg struct {
	ErrCode int64  `json:"errcode"`
	ErrMsg  string `json:"errmsg"`
}

var msgCache *cache.Cache

func init() {
	msgCache = cache.New(
		time.Minute*10,
		time.Minute*120,
	)
}

// SendDD 发送钉钉信息
func SendDD(msg string, mobiles []string, gConf *options.GlobalOPT) {
	if gConf.ExtOPT["dingding_secret"] == "" {
		fmt.Printf("msg: %s\n", msg)
	}
	key := utils.MD5([]byte(msg), "hex")
	if v, ok := msgCache.Get(key); ok {
		msgCache.Set(key, v.(int32)+1, 0)
		return
	} else {
		msgCache.Set(key, int32(1), 0)
	}
	timestamp := strconv.FormatInt(time.Now().UnixMilli(), 10)
	stringToSign := timestamp + "\n" + gConf.ExtOPT["dingding_secret"]
	hm := hmac.New(sha256.New, []byte(gConf.ExtOPT["dingding_secret"]))
	hm.Write([]byte(stringToSign))
	checksum := hm.Sum(nil)
	encodeBase64 := base64.StdEncoding
	data := make([]byte, sha256.Size)
	copy(data, checksum[:sha256.Size])
	sec := encodeBase64.EncodeToString(data)
	sign := url.QueryEscape(sec)
	params := url.Values{}
	params.Add("access_token", gConf.ExtOPT["dingding_token"])
	params.Add("timestamp", timestamp)
	params.Add("sign", sign)
	// params.Encode()
	ddMsg := vmap.V{
		"msgtype": "text",
		"at": vmap.V{
			"atMobiles": mobiles,
		},
		"text": vmap.V{
			"content": msg,
		},
	}
	request := gorequest.New()
	request.Client.Timeout = time.Second * 60
	resp, body, errs := request.Post("https://oapi.dingtalk.com/robot/send?"+params.Encode()).
		Set("Content-Type", "application/json; charset=utf-8").
		Send(ddMsg).End()
	if len(errs) > 0 || resp.StatusCode != 200 {
		gConf.ErrLog.LogWarning("send dingding failed: %v; body: %s", errs, body)
		return
	}
	respMsg := RespMsg{}
	err := json.Unmarshal([]byte(body), &respMsg)
	if err != nil {
		gConf.ErrLog.LogWarning("dingding response msg invaild: %v; body: %s", err, body)
		return
	}
	if respMsg.ErrCode != 0 {
		gConf.ErrLog.LogWarning("dingding response msg failed: %s", body)
	}
}
